import { Compiler, Component, ComponentFactory, ComponentRef, EventEmitter, Injector, NgModule, OnDestroy, Output, ViewChild, ViewContainerRef } from '@angular/core';
import { AppSharedModule } from '@app/shared/app-shared.module';
import { AppComponentBase } from '@shared/common/app-component-base';
import { FileUploadHelper } from '@shared/helpers/FileUploadHelper';
import { ContentConfig, CreateOrUpdateImageTextInput, CreateOrUpdateSeoInput, EntityDtoOfGuid, FormField, ManualSyncInput, MenuAndIdInputOfGuid, MenuInfoConfig, MenuInfoServiceProxy, MenuInfoSyncServiceProxy, SeoDto, SeoServiceProxy } from '@shared/service-proxies/service-proxies';
import { ModalDirective } from 'ngx-bootstrap/modal';
import { finalize } from 'rxjs/operators';
import { DiyFormService } from '../diy-form-service';
import { MainSharedModule } from '../main-shared.module';
import { ImageTextService } from './imageText.service';


@Component({
    selector: 'menu-extend-modal',
    templateUrl: './menu-extend-modal.component.html'
})
export class MenuExtendModalComponent extends AppComponentBase implements OnDestroy {

    @Output() callback: EventEmitter<any> = new EventEmitter<any>();

    @ViewChild('modal', { static: true }) modal: ModalDirective;
    @ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;
    cmpRef: ComponentRef<any>;

    saving = false;
    kind: number;
    menuId: string;

    dataSynchronous: boolean = false;
    formConfig: FormField[];

    data: { [key: string]: any; };

    permissions: { [key: string]: boolean; } = {};
    permissionDic: { [key: string]: boolean; }

    private dataKey: string;

    randomId: string;
    isTemporary: boolean;

    constructor(
        injector: Injector,
        private compiler: Compiler,
        private _diyFormService: DiyFormService,
        private _menuInfoServiceProxy: MenuInfoServiceProxy,
        private _menuInfoSyncServiceProxy:MenuInfoSyncServiceProxy
    ) {
        super(injector);
    }

    show(kind: number, menuId: string, permissionDic: { [key: string]: boolean; }, formConfig:  FormField[], dataKey: string, id: string) {
        this.dataSynchronous = this.setting.getBoolean("App.Synchronous.DataSynchronous");
        this.permissionDic = permissionDic;
        this.permissions.extendedDataEdit = permissionDic['Pages.Tenant.MenuInfo.ExtendedData.Edit'];
        this.dataKey = dataKey;

        this.formConfig = formConfig;
        this.data = {};
        this.saving = false;
        this.menuId = menuId;
        this.kind = kind;

        if (this.cmpRef) {
            this.cmpRef.destroy();
        }

        this.modal.show();

        if (this.dataKey === ImageTextService.extendKey) {
            this._menuInfoServiceProxy.getSingleDataForEdit(undefined, this.kind, this.menuId, this.dataKey)
                .subscribe(result => {
                    this.bindFormData(result);
                });
        } else {
            this._menuInfoServiceProxy.getListDataForEdit(id, this.kind, this.menuId, this.dataKey)
                .subscribe(result => {
                    this.bindFormData(result);
                });
        }
    }

    private bindFormData(result:{ [key: string]: any; }){
        this._diyFormService.afterLoadData(this.formConfig, result);
        this.data = result;

        if (this.data.id) {
            this.randomId = this.data.id;
            this.isTemporary = false;
        } else {
            this.randomId = FileUploadHelper.newGuid();
            this.isTemporary = true;
        }

        let that = this;
        let tempFunc = function () {
            this.data = that.data;
            this.permissionDic = that.permissionDic;
            this.kind = that.kind;
            this.randomId = that.randomId;
            this.isTemporary = that.isTemporary;
        };

        let html = this._diyFormService.getDetailPageTemplate(this.formConfig);
        this._diyFormService.createFormComponentFactory(this.compiler, html, tempFunc).then(factory => {
            const injector = Injector.create({ providers: [], parent: this.vc.injector });
            const cmpRef = this.vc.createComponent(factory, 0, injector, []);

            cmpRef.instance.name = "dynamic-extend-component";

            this.cmpRef = cmpRef;
        });
    }

    ngOnDestroy() {
        if (this.cmpRef) {
            this.cmpRef.destroy();
        }
    }

    save() {
        this.saving = true;
        let input = new CreateOrUpdateImageTextInput();
        if (this.data.id) {
            input.id = this.data.id;
        }else{
            input.randomId = this.randomId;
        }
        
        let field: { [key: string]: any } = {};
        for (let key in this.data) {
            field[key] = this.data[key];
        }
        this._diyFormService.beforeSubmit(this.formConfig, field);

        input.values = field;
        input.menuId = this.kind;
        input.dataKey = this.dataKey;

        if (this.dataKey === ImageTextService.extendKey) {
            this._menuInfoServiceProxy.createOrUpdateExtendedData(input)
            .pipe(finalize(() => { this.saving = false; }))
            .subscribe(result => {
                this.callback && this.callback.emit(this.dataKey);
                this.notify.success(this.l('SavedSuccessfully'));
                this.close();
            })
        }else{
            this._menuInfoServiceProxy.createOrUpdateImageText(input)
            .pipe(finalize(() => { this.saving = false; }))
            .subscribe(result => {
                this.callback && this.callback.emit(this.dataKey);
                this.notify.success(this.l('SavedSuccessfully'));
                this.close();
            })
        }
    }

    synchorization() {
        this.message.confirm(this.l('ManualSyncWarningMessage'), this.l('AreYouSure'),
            (isConfirmed) => {
                if (!isConfirmed) return;
                let manualSyncInput = new ManualSyncInput();
                manualSyncInput.id = this.menuId;
                this._menuInfoSyncServiceProxy.setExtendedData(manualSyncInput).subscribe(result=>{
                    if (result && result.syncResult){
                        this.notify.success(this.l('ManualSynchorizationSuccessfully'))
                    }
                    else {
                        this.notify.success(this.l('ManualSynchorizationFail'))
                    }
                })
            })
    }
    close(): void {
        if (this.cmpRef) {
            this.cmpRef.destroy();
        }
        this.modal.hide();
    }
}
